﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <vector>

#ifdef WIN32
#define _USE_MATH_DEFINES  // 必须在包含 <math.h> 之前定义
#include <math.h>
#else
#include <cmath>
#endif

#include <complex>
#include <fftw3.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //input
    ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    ui->widget->xAxis->setLabel(tr("时间(秒)"));
    ui->widget->yAxis->setLabel(tr("频率"));
    ui->widget->xAxis->setRange(0, 1);
    ui->widget->yAxis->setRange(-5, 5);  // 动态范围‌
    ui->widget->addGraph();

    //output
    ui->widget_2->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    ui->widget_2->xAxis->setLabel(tr("时间(秒)"));
    ui->widget_2->yAxis->setLabel(tr("频率"));
    ui->widget_2->xAxis->setRange(0, 1);
    ui->widget_2->yAxis->setRange(-5, 5);  // 动态范围‌
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    // 参数设置
    const double fs = 1000.0;      // 采样率 (Hz)
    const double duration = 1.0;    // 信号时长 (秒)
    const int N = fs * duration;    // 采样点数

    QVector<double> xData,yData;

    // 生成信号：150Hz + 360Hz
    std::vector<double> signal(N);
    for (int i = 0; i < N; ++i) {
        double t = i / fs;
        signal[i] = 0.7 * sin(2 * M_PI * 150 * t) + 1.0 * sin(2 * M_PI * 360 * t);

        xData.push_back(t);
        yData.push_back(signal[i]);
        ui->widget->graph(0)->setData(xData, yData);  // 数据绑定‌
    }
    ui->widget->replot();

    // 分配FFTW输入/输出数组
    fftw_complex *spectrum = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    double *fft_input = (double*) fftw_malloc(sizeof(double) * N);

    // 准备输入数据
    for (int i = 0; i < N; ++i) {
        fft_input[i] = signal[i];
    }

    // 创建FFT计划并执行
    fftw_plan plan = fftw_plan_dft_r2c_1d(N, fft_input, spectrum, FFTW_ESTIMATE);
    fftw_execute(plan);

    //分离出每个频率
    // 提取幅度和相位 (频谱是对称的，只需前N/2点)
    int nGraphIndex = 0;
    for(int j=0; j<N/2; j++){
        double magnitude = 2.0 * sqrt(spectrum[j][0] * spectrum[j][0] + spectrum[j][1] * spectrum[j][1]) / N;
        double phase = atan2(spectrum[j][1], spectrum[j][0]);
        double freq = j/(N/fs);
        qDebug() << tr("j:") << j << tr("幅度Hz: ") << QString::number(magnitude, 'f', 2) << tr("相位: ") << phase << tr("弧度") << tr("频率Hz: ")  << freq;

        if(fabs(magnitude) <= 0.000001){
            continue;
        }

        ui->widget_2->addGraph();
        if(0 == nGraphIndex % 3){
            ui->widget_2->graph(nGraphIndex)->setPen(QPen(QColor(255, 0, 0)));    // 红色
        }
        else  if(1 == nGraphIndex % 3){
           ui->widget_2->graph(nGraphIndex)->setPen(QPen(QColor(0, 255, 0)));    // 绿色
        }
        else{
           ui->widget_2->graph(nGraphIndex)->setPen(QPen(QColor(0, 0, 255)));    // 蓝色
        }

        // 重建目标频率信号
        QVector<double> xOutputData,yOutputData;
        std::vector<double> extracted(N);
        for (int i = 0; i < N; ++i) {
            double t = i / fs;
            //重建目标频率信号
            extracted[i] = magnitude * cos(2 * M_PI * freq * t + phase);
            xOutputData.push_back(t);
            yOutputData.push_back(extracted[i]);
        }
        ui->widget_2->graph(nGraphIndex)->setData(xOutputData,yOutputData);
        ui->widget_2->replot();
        nGraphIndex++;
    }

    // 释放资源
    fftw_destroy_plan(plan);
    fftw_free(spectrum);
    fftw_free(fft_input);
}

